package com.googlecode.alfresco_caching_server.webscripts.bean;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Container;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScript;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;

import com.googlecode.alfresco_caching_server.webscripts.ServerCacheConfig;

/**
 * Index of all Server-Cachable Web Scripts
 * 
 * @author dimyjeannot
 */
public class IndexCache extends DeclarativeWebScript
{

	private static Log logger = LogFactory.getLog(IndexCache.class);
    
	
    /* (non-Javadoc)
     * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.Status)
     */
    @Override
    protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
    {
        
        // filter web scripts
    	Collection<WebScript> scripts = getContainer().getRegistry().getWebScripts();
    	Collection<Object> filteredWebScripts = new ArrayList<Object>();
    	
    	for (WebScript script : scripts)
    	{
    		try
            {
        		ServerCacheConfig serverCacheConfig = getServerCacheConfig(script);
        		if(serverCacheConfig != null && serverCacheConfig.isCacheable())
        		{
        			Map<String, Serializable> cacheableScriptData = new HashMap<String, Serializable>();
        			cacheableScriptData.put("shortname", script.getDescription().getShortName());
        			cacheableScriptData.put("method", script.getDescription().getMethod());
        			//cacheableScriptData.put("uris", script.getDescription().getURIs());
        			cacheableScriptData.put("uris", serverCacheConfig.getURIs());
        			cacheableScriptData.put("cache", serverCacheConfig.getCache());
        			
        			filteredWebScripts.add(cacheableScriptData);
        		}
            }
        	catch (IOException ioe)
            {
                throw new WebScriptException("Failed to read server cache configuration file", ioe);
            }
    	}

        // setup model
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("webscripts", filteredWebScripts);
    	return model;
    }
    
    /**
     * Looks for the script's config file and reads it's contents
     * if present. The result is the XML config stored in the
     * <code>xmlConfig</code> member variable.
     */
    private synchronized ServerCacheConfig getServerCacheConfig(WebScript script) throws IOException
	{
    	
    	ServerCacheConfig serverCacheConfig = null;
    	InputStream input = null;
    	Container container = getContainer();
    	
        try
        {
            // Look for script's server cache config file
            String configPath = script.getDescription().getId() + ".cache.xml";
            //logger.debug("Config Path " + configPath);
            
            if (container.getSearchPath().hasDocument(configPath))
            {
            	input = container.getSearchPath().getDocument(configPath);
            	
            	ServerCacheConfig scc = new ServerCacheConfig(input, script);
            	
            	if(scc != null)
            	{
            		serverCacheConfig = scc;
            	}
            }
        }
        catch (IOException ioe)
        {
            throw new WebScriptException("Failed to read server cache configuration file", ioe);
        }
        
        return serverCacheConfig;
	}
    
}
